/*
 * Resources.java
 *
 * Created on October 11, 2009, 3:07 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package com.nextel.util.lwuit;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
//import java.util.Enumeration;
//import java.util.Hashtable;

/**
 * Loads resources from the binary resource file generated during the build process or via the LWUIT Designer.
 * A resource is loaded entirely into memory since random file access is not supported
 * in Java ME, any other approach would be inefficient. This means that memory must
 * be made available to accommodate the resource file.
 *
 * @author Shai Almog
 */
public class Resources {
    
    /**
     * Magic numbers to prevent data corruption
     */
    static final byte MAGIC_FONT = (byte) 0xFC;
    static final byte MAGIC_HEADER = (byte) 0xFF;
//    private short majorVersion;
//    private short minorVersion;
//    // for use by the resource editor
//    private static Class classLoader = Resources.class;
//
//    static void setClassLoader(Class cls) {
//        classLoader = cls;
//    }
//
    /**
     * A cache within the resource allowing us to preserve some resources in memory
     * so they can be utilized by a theme when it is loaded
     */
//    private Hashtable resources = new Hashtable();
    private DataInputStream input;
    
    // for internal use by the resource editor, creates an empty resource
//    Resources() {
//    }
    Resources(InputStream input) throws IOException {
        openFile(input);
    }
    
    void clear() {
//        majorVersion = 0;
//        minorVersion = 0;
//        resourceTypes.clear();
//        resources.clear();
        input = null;
    }
    
    void openFile(InputStream input) throws IOException {
        clear();
        this.input = new DataInputStream(input);
        int resourceCount = this.input.readShort();
        
        if (resourceCount < 0) {
            throw new IOException("Invalid resource file!");
        }
        
        for (int iter = 0; iter < resourceCount; iter++) {
            byte magic = this.input.readByte();
            
//            System.out.println("magic=" + magic);
            
            String id = this.input.readUTF();
            
            switch (magic) {
                case MAGIC_HEADER:
                    readHeader();
                    continue;
                    
                case MAGIC_FONT:
//                    setResource(id, magic, loadFont(this.input, id, false));
                    loadFont(this.input, id, false);
                    continue;
                    
                default:
                    throw new IOException("Corrupt theme file unrecognized magic number: " + Integer.toHexString(magic & 0xff));
            }
        }
    }
    
    /**
     * Reads the header of the resource file
     */
    private void readHeader() throws IOException {
        input.readShort();
        input.readShort();
        input.readShort();
        input.readShort();
        
//        System.out.println("majorVersion=" + 2);
//        System.out.println("minorVersion=" + 1);
    }
    
    /**
     * Creates a resource object from the local JAR resource identifier
     *
     * @param resource a local reference to a resource using the syntax of Class.getResourceAsStream(String)
     * @return a resource object
     * @throws java.io.IOException if opening/reading the resource fails
     */
    public static void open(String resource) throws IOException {
        try {
            InputStream is = Resources.class.getResourceAsStream(resource);
            Resources r = new Resources(is);
            is.close();
            is = null;
            r.clear();
            r = null;
            System.gc();
        } catch (Exception err) {
            // intercept exceptions since user code might not deal well with runtime exceptions
            err.printStackTrace();
            throw new IOException(err.getMessage());
        }
    }
    
    Image createImage() throws IOException {
        
        int type = input.readByte() & 0xff;
        
//        System.out.println("type=" + type);
//
//        System.out.println("0xf1=" + 0xf1);
//        System.out.println("0xf5=" + 0xf5);
        
        switch (type) {
            // PNG file
            case 0xf1:
                
                // JPEG File
            case 0xf2:
                byte[] data = new byte[input.readInt()];
                input.readFully(data, 0, data.length);
                return Image.createImage(data,0,data.length);
                
                // Fail this is the wrong data type
            default:
                throw new IOException("Illegal type while creating image: " + Integer.toHexString(type));
        }
        
    }
    
    void loadFont(DataInputStream input, String id, boolean packed) throws IOException {
        // read a system font fallback
        input.readByte();
        
        // do we have an emedded truetype font? Do we support embedded fonts?
        boolean trueTypeIncluded = input.readBoolean();
        //Font font = null;
        if (trueTypeIncluded) {
            int size = input.readInt();
            
            while (size > 0) {
                size -= input.skip(size);
            }
        }
        boolean lookupIncluded = input.readBoolean();
        if (lookupIncluded) {
            input.readUTF();
        }
        boolean bitmapIncluded = input.readBoolean();
        if (bitmapIncluded) {
            loadBitmapFont(input, id);
        }
        
    }
    
    
    //@zico - es el que carga el bitmap del font
    void loadBitmapFont(DataInputStream input, String id) throws IOException {
        Image bitmap = createImage();
        int charCount = input.readShort();
        int[] cutOffsets = new int[charCount];
        int[] charWidth = new int[charCount];
//        System.out.println("cargando un loadBitmapFont(DataInputStream input, String id, com.sun.lwuit.Font font)");
        for (int iter = 0; iter < charCount; iter++) {
            cutOffsets[iter] = input.readShort();
//            System.out.println("cutOffsets[iter] : " + cutOffsets[iter]);
        }
        for (int iter = 0; iter < charCount; iter++) {
            charWidth[iter] = input.readByte();
//            System.out.println("charWidth[iter] : " + charWidth[iter]);
        }
        
        String charset = input.readUTF();
        input.readByte();
        
        //bitmap
        Font.createBitmapFont(id, bitmap, cutOffsets, charWidth, charset);
        bitmap.clear();
        bitmap = null;
//        }
//        old = null;
        System.gc();
//            }
//        }
//        return font;
    }
}
